package com.turnengine.client.local.unit;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentSkipListSet;

import com.javabi.common.lang.ThreadSafe;
import com.turnengine.client.local.faction.bean.IFaction;
import com.turnengine.client.local.group.bean.IGroup;
import com.turnengine.client.local.unit.bean.IUnit;
import com.turnengine.client.local.unit.enums.UnitMove;
import com.turnengine.client.local.unit.enums.UnitNode;
import com.turnengine.client.local.unit.enums.UnitType;

@ThreadSafe
public class UnitCache implements IUnitCache {

	private final Set<IUnit> unitSet = new ConcurrentSkipListSet<IUnit>();

	public UnitCache() {
	}

	public UnitCache(Collection<IUnit> units) {
		addUnits(units);
	}

	@Override
	public void clear() {
		unitSet.clear();
	}

	@Override
	public int size() {
		return unitSet.size();
	}

	@Override
	public boolean addUnit(IUnit unit) {
		return unitSet.add(unit);
	}

	@Override
	public boolean containsById(int id) {
		for (IUnit unit : unitSet) {
			if (unit.getId() == id) {
				return true;
			}
		}
		return false;
	}

	@Override
	public boolean containsByName(String name) {
		for (IUnit unit : unitSet) {
			if (unit.getName().equals(name)) {
				return true;
			}
		}
		return false;
	}

	@Override
	public IUnit getById(int id) {
		for (IUnit unit : unitSet) {
			if (unit.getId() == id) {
				return unit;
			}
		}
		throw new IllegalArgumentException("id=" + id + ", unitSet=" + unitSet);
	}

	@Override
	public IUnit getByName(String name) {
		for (IUnit unit : unitSet) {
			if (unit.getName().equals(name)) {
				return unit;
			}
		}
		throw new IllegalArgumentException("name: " + name + ", unitSet=" + unitSet);
	}

	@Override
	public List<IUnit> getByFactionId(int factionId) {
		List<IUnit> set = new ArrayList<IUnit>();
		for (IUnit unit : unitSet) {
			if (unit.getFactionId() == factionId) {
				set.add(unit);
			}
		}
		return set;
	}

	@Override
	public List<IUnit> getByGroupId(int groupId) {
		List<IUnit> set = new ArrayList<IUnit>();
		for (IUnit unit : unitSet) {
			if (unit.getGroupId() == groupId) {
				set.add(unit);
			}
		}
		return set;
	}

	@Override
	public List<IUnit> getByType(UnitType type) {
		List<IUnit> set = new ArrayList<IUnit>();
		for (IUnit unit : unitSet) {
			if (unit.getType().equals(type)) {
				set.add(unit);
			}
		}
		return set;
	}

	@Override
	public List<IUnit> getByMove(UnitMove move) {
		List<IUnit> set = new ArrayList<IUnit>();
		for (IUnit unit : unitSet) {
			if (unit.getMove().equals(move)) {
				set.add(unit);
			}
		}
		return set;
	}

	@Override
	public List<IUnit> getByNode(UnitNode node) {
		List<IUnit> set = new ArrayList<IUnit>();
		for (IUnit unit : unitSet) {
			if (unit.getNode().equals(node)) {
				set.add(unit);
			}
		}
		return set;
	}

	@Override
	public Iterator<IUnit> iterator() {
		return getAll().iterator();
	}

	@Override
	public List<IUnit> getAll() {
		return new ArrayList<IUnit>(unitSet);
	}

	@Override
	public List<IUnit> getByFaction(IFaction faction) {
		return getByFactionId(faction.getId());
	}

	@Override
	public List<IUnit> getByGroup(IGroup group) {
		return getByGroupId(group.getId());
	}

	@Override
	public int addUnits(Collection<IUnit> units) {
		int added = 0;
		for (IUnit unit : units) {
			if (addUnit(unit)) {
				added++;
			}
		}
		return added;
	}

	@Override
	public String toString() {
		return getAll().toString();
	}

}
